package br.com.itc.componentes.input
{
	import br.com.itc.componentes.validacao.IValidavel;
	
	import flash.events.Event;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.IList;
	import mx.collections.ListCollectionView;
	import mx.controls.ComboBox;
	import mx.events.FlexEvent;
	import mx.events.ListEvent;
	import mx.validators.Validator;
	
	public class ComboBoxITC extends ComboBox implements IValidavel
	{
		
		private var _campoObrigatorio: Boolean = false;
		private var _descricaoErro: String = "Campo Obrigatório!";
		private var validator: Validator = new Validator;
		
		private var _itemOpcional: Boolean;
		
		private var _labelCampoOpcional: String = "---";
		
		public function get itemOpcional(): Boolean {
			return this._itemOpcional;
		}
		
		public function set itemOpcional(itemOpcional: Boolean): void {
			this._itemOpcional = itemOpcional;
		}
		
		public function get labelCampoOpcional(): String {
			return this._labelCampoOpcional;
		}
		
		public function set labelCampoOpcional(labelCampoOpcional: String): void {
			this._labelCampoOpcional = labelCampoOpcional;
		}
		
		public function get campoObrigatorio(): Boolean {
			return _campoObrigatorio;
		}
		
		public function set campoObrigatorio(isObrigatorio: Boolean): void {
			this._campoObrigatorio = isObrigatorio;
		}
		
		public function get descricaoErro(): String {
			return _descricaoErro;
		}
		
		public function set descricaoErro(descricaoErro: String): void {
			this._descricaoErro = descricaoErro;
		}
		
		public function ComboBoxITC()
		{
			this.addEventListener(FlexEvent.CREATION_COMPLETE, init);
		}
		
		private function init(event: FlexEvent): void {
			if(_campoObrigatorio) {
				this.addEventListener(ListEvent.CHANGE, validar);
				validator.source = this;
				validator.property = "selectedItem";
				validator.required = true;
				validator.requiredFieldError = _descricaoErro;
				validar(null);
			}
		}
		
	    override public function set dataProvider(value: Object): void {
	    	var colecao: Object = value;
		    
		    if (_itemOpcional) {
		        if (value is Array) {
		            colecao = new ArrayCollection(value as Array);
		        } else if (value is IList) {
		            colecao = new ListCollectionView(IList(value));
		        } else if (value is ICollectionView) {
		            throw new TypeError("Uma IList é requerida por esta implementação.");
		        } else if (value is XMLList) {
		            throw new TypeError("Uma IList é requerida por esta implementação.");
		        } else {
		            var tmp: Array = [value];
		            colecao = new ArrayCollection(tmp);
		        }
            	adicionarItemOpcional(colecao);
		    }

		    super.dataProvider = colecao;
	    }
	    
	    override public function get selectedItem():Object {
			var object:Object = super.selectedItem;

			if (object != null 
					&& object.hasOwnProperty(labelField) 
					&& object[labelField] == labelCampoOpcional) {
				return null;
			}
			return object;
		}
		
		/**
	     *  @private
	     */
		override public function set selectedItem(item: Object): void {
			
			if(this.dataProvider == null) {
				return;
			}
			if (item == null && itemOpcional) {
				super.selectedIndex = 0;
				return;
			}
			super.selectedItem = item;
		}
		
		override public function get selectedLabel():String {
	    	if (selectedItem == null && _itemOpcional) {
	    		return labelCampoOpcional;
	    	}

	    	return super.selectedLabel;
	    }
	    
		private function adicionarItemOpcional(colecao: Object): void {
			if (_itemOpcional && (colecao is IList)) {
				var lista: IList = (colecao as IList);
				if (lista.length == 0 || lista.getItemAt(0) != null) {
					lista.addItemAt(criarItemOpcional(), 0);
				}
			}
		}
		
		protected function criarItemOpcional(): Object {
			var objeto: Object = new Object();

			if (labelField != null) {
				objeto[labelField] = labelCampoOpcional;
			} else {
				objeto.label = labelCampoOpcional;
			}
			return objeto;
		}
		
		private function validar(evt: Event = null): void {
			dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
			resourceManager.update();
		}
		
		public function isValido(): Boolean {
			var valido: Boolean = true;
			if (_campoObrigatorio && selectedItem == null) {
				valido = false;
			}
			return valido;
		}

	}
}